-
Notifications
You must be signed in to change notification settings - Fork 415
Introduce splice-compatible commitment update monitor variants #3855
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce splice-compatible commitment update monitor variants #3855
Conversation
👋 Thanks for assigning @tankyleo as a reviewer! |
let htlcs_for_commitment = |commitment: &CommitmentTransaction| { | ||
let mut nondust_htlcs = commitment.nondust_htlcs().clone().into_iter(); | ||
let mut sources = htlc_data.nondust_htlc_sources.clone().into_iter(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not too happy with this, but trying to not duplicatively track the HTLC sources across FundingScope
s is a good bit of non-trivial work. At least they'll only exist in the current and previous counterparty commitments, but those are still per FundingScope
. The simplest thing we could do for now is Arc
them to reduce memory bandwidth (unfortunately on disk we'll still have duplicates), but I chose not to pursue that unless we're sure of it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given its just for the latest and prev commitment txn I feel like its okay. It also gives us room to relax the restriction on multiple splices having the same dust/non-dust HTLC sets in the future.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3855 +/- ##
==========================================
- Coverage 89.65% 88.80% -0.86%
==========================================
Files 164 165 +1
Lines 134658 119288 -15370
Branches 134658 119288 -15370
==========================================
- Hits 120734 105937 -14797
+ Misses 11246 11020 -226
+ Partials 2678 2331 -347 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks dude, just went through the first commit, will continue tomorrow. I have a big-picture question in commitment_signed_batch
take a look at that first.
let msg = messages | ||
.get(&funding_txid) | ||
.ok_or_else(|| ChannelError::close(format!("Peer did not send a commitment_signed for pending splice transaction: {}", funding_txid)))?; | ||
let (commitment_tx, htlcs_included) = self.context.validate_commitment_signed( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might not be worth the pain let me know:
Can we avoid doing the work of populating and sorting this table for all the pending scopes in build_commitment_transaction
? We only need it for the current scope here.
(In validate_commitment_signed
, let's read the HTLCs from the commitment transaction instead of the HTLC-source table).
Also wondering if we can make the state and dust-vs-nondust HTLC sorting only once for all scopes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm yeah this would be nice, this code was mostly written before we made the change to populate the source table separately. I wouldn't consider it a blocker to this PR, unless @TheBlueMatt feels strongly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Went through the second commit, some similar questions, some new ones.
@@ -3175,11 +3171,11 @@ impl<Signer: EcdsaChannelSigner> ChannelMonitorImpl<Signer> { | |||
self.counterparty_hash_commitment_number.insert(htlc.payment_hash, commitment_number); | |||
} | |||
|
|||
log_trace!(logger, "Tracking new counterparty commitment transaction with txid {} at commitment number {} with {} HTLC outputs", txid, commitment_number, htlc_outputs.len()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You find this log not necessary ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@wpaulino just want to confirm here - i think the worry is hey these could be used to cheat so make sure we are tracking them ?
🔔 1st Reminder Hey @TheBlueMatt! This PR has been waiting for your review. |
🔔 2nd Reminder Hey @TheBlueMatt! This PR has been waiting for your review. |
let htlcs_for_commitment = |commitment: &CommitmentTransaction| { | ||
let mut nondust_htlcs = commitment.nondust_htlcs().clone().into_iter(); | ||
let mut sources = htlc_data.nondust_htlc_sources.clone().into_iter(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given its just for the latest and prev commitment txn I feel like its okay. It also gives us room to relax the restriction on multiple splices having the same dust/non-dust HTLC sets in the future.
7f942f4
to
fedd0ff
Compare
fedd0ff
to
0e88cdf
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another pass on the first commit, will continue first thing tomorrow...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done with the two other commits
🔔 1st Reminder Hey @TheBlueMatt! This PR has been waiting for your review. |
Mind addressing @tankyleo's feedback? |
This new variant is a backwards-incompatible successor to `LatestHolderCommitmentTXInfo` that is capable of handling holder commitment updates while a splice is pending. Since all holder commitment candidates share the same set of non-dust and dust HTLCs (though each non-dust HTLC can have differing output indices), we can share the same set of HTLC source data across all candidates.
This new variant is a backwards-incompatible successor to `LatestCounterpartyCommitmentTXInfo` that is capable of handling counterparty commitment updates while a splice is pending. Since all counterparty commitment candidates share the same set of non-dust and dust HTLCs (though each non-dust HTLC can have differing output indices), we can share the same set of HTLC source data across all candidates. Unfortunately, each `FundingScope` tracks its own set of `counterparty_claimable_outpoints`, which includes the HTLC source data (though only for the current and previous counterparty commitments), so we end up duplicating it (both in memory and on disk) temporarily.
They don't need to be tracked as we can recompute them easily, though we still write them in the `ChannelMonitor` for the current `FundingScope` for backwards compatibility. The serialization implementation for `FundingScope` can now use the `impl_writeable_tlv_based` macro as a result.
0e88cdf
to
4dc47f9
Compare
fn update_counterparty_commitment_data( | ||
&mut self, commitment_txs: &[CommitmentTransaction], htlc_data: &CommitmentHTLCData, | ||
) -> Result<(), &'static str> { | ||
self.verify_matching_commitment_transactions(commitment_txs.iter())?; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The function verify_matching_commitment_transactions
returns a Result
, but the error case isn't being handled here. Consider propagating the error back to the caller by changing this to:
self.verify_matching_commitment_transactions(commitment_txs.iter())?;
This matches the pattern used in update_holder_commitment_data
and ensures errors aren't silently ignored.
Spotted by Diamond
Is this helpful? React 👍 or 👎 to let us know.
🔔 1st Reminder Hey @TheBlueMatt @tankyleo! This PR has been waiting for your review. |
1 similar comment
🔔 1st Reminder Hey @TheBlueMatt @tankyleo! This PR has been waiting for your review. |
|
||
let current_funding_commitment_tx = commitment_txs.first().unwrap(); | ||
self.current_holder_commitment_number = current_funding_commitment_tx.commitment_number(); | ||
self.onchain_tx_handler.provide_latest_holder_tx(current_funding_commitment_tx.clone()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mind leaving a comment here on why OnchainTxHandler
doesn't need to know about other commitments?
let source = (!htlc.offered).then(|| { | ||
let source = sources | ||
.next() | ||
.expect("Every inbound non-dust HTLC should have a corresponding source") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We generally call these "outbound" HTLCs, since they're outbound, just !offered on the commitment tx.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah yes my bad should be every outbound :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nothing blocking, just have a pending question further above about why we delete
log_trace!(logger, "Tracking new counterparty commitment transaction with txid {} at commitment number {} with {} HTLC outputs", txid, commitment_number, htlc_outputs.len());
Landing this, we can figure out the logging and comments in a followup. |
No description provided.